<?php
namespace Api\Controller;
class NotifyCallbackController extends CommonController{
    private $Notify_Data = array();
    public function _initialize(){
        $Notifydata = parseData();
        if(empty($Notifydata)){
            $Notifydata = xmlToArray(file_get_contents('php://input'));
        }
        $this->Notify_Data = $Notifydata;
    }

    private function Notify($ClassName,$pay_info , $wx_orderId = ''){
        $logname = $ClassName;
        $instantiation = "\\Com\\Pay\\" . $ClassName;
        $mchData = M('mch_data')->where(array('mch_id' => $pay_info['mch_id']))->find();
        $payObj = new $instantiation(array('mch_id' => $mchData['mch_id'] , 'mch_key' => $mchData['mch_key'] , 'appid' => $mchData['appid']));
//        file_put_contents('./obj.txt',var_export($payObj,true));
        $param = $payObj->response();
        if ($param == true) {   //签名通过
            \Think\Log::write("SignSuccess-" . $pay_info['order_number'], 'INFO', '', LOG_PATH . "Api/CallbackLog/". $logname ."/" . date('Y-m-d') . ".log");
            $result = $this->paySuccess($pay_info['order_number'],$pay_info['pay_money'], $logname , $wx_orderId);
            if ($result === true) {
                ob_clean();
                echo $pay_info['success_msg'];
                return;
            } else {
                ob_clean();
                echo $pay_info['fail_msg'];
                return;
            }
        } else {
            $data = array('msg' => 'order sign ERR', 'orderId' => $pay_info['order_number']);
            \Think\Log::write(json_encode($data), 'ERROR', '', LOG_PATH . "Api/CallbackLog/" . $logname ."/" . date('Y-m-d') . ".log");
            echo $pay_info['fail_msg'];
            return;
        }
    }

    /* 官方支付宝回调 */
    public function AlipayPay(){
        $this->KeyValname('AlipayPay' , $this->Notify_Data['seller_id'] , $this->Notify_Data['out_trade_no'] , $this->Notify_Data['total_fee'] , "success" , 'fail');
    }

    /* 官方微信回调 */
    public function WeixinGzhNotify(){
        $this->KeyValname('WeixinGzhPay' , $this->Notify_Data['mch_id'] , $this->Notify_Data['out_trade_no'] , $this->Notify_Data['total_fee'] / 100 , "success" , 'fail');
    }

    public function BenfuNotify(){
        // pay_name 写类名
        if($this->Notify_Data['rc_BankCode'] == 'QQ_NATIVE') {
            $Class_name = 'QQBenfuPay';
        }elseif($this->Notify_Data['rc_BankCode'] == 'ALIPAY_PAY') {
            $Class_name = 'benFuAlipayPay';
        }elseif($this->Notify_Data['rc_BankCode']  == 'WEIXIN_NATIVE') {
            $Class_name = 'benFuSmPay';
        }else{
            $Class_name = 'benfuBankPay';
        }
        $this->KeyValname($Class_name , $this->Notify_Data['r1_MerchantNo'] , $this->Notify_Data['r2_OrderNo'] , $this->Notify_Data['r3_Amount'] , "SUCCESS" , 'FAILED');
    }

    public function BenfuNotify1(){
        $Class_name = "benFuGzhPay";
        file_put_contents('./benfuGzhCallback.txt' , var_export($this->Notify_Data,true));
        $this->KeyValname($Class_name , $this->Notify_Data['r1_MerchantNo'] , $this->Notify_Data['r2_OrderNo'] , $this->Notify_Data['r3_Amount'] , "SUCCESS" , 'FAILED');
    }

    public function OuchuangAlipayPay(){
        // pay_name 写类名
        $Class_name = 'OuchuangGzhPay';
        $this->KeyValname($Class_name , $this->Notify_Data['mchtId'] , $this->Notify_Data['transactionId'] , $this->Notify_Data['totalamt'] , "SUCCESS" , 'FAILED');
    }

    public function XunDaPayNotify(){
        // pay_name 写类名
        $Class_name = 'XunDaPay';
        $this->KeyValname($Class_name , $this->Notify_Data['mch_id'], $this->Notify_Data['pay_number'] , $this->Notify_Data['amount'] , "SUCCESS" , 'FAILED');
    }

    public function OuchuangGzhPay(){
        // pay_name 写类名
        file_put_contents('./ouchuang.txt' , var_export($this->Notify_Data,true));
        $Class_name = 'OuchuangGzhPay';
        $this->KeyValname($Class_name , $this->Notify_Data['mchtId'] , $this->Notify_Data['out_trade_no'] , $this->Notify_Data['total_amt'] , "SUCCESS" , 'FAILED');
    }
    public function ZhifutongPayNotify(){
        // pay_name 写类名
        $Class_name = 'ZhifutongPay';
        $this->KeyValname($Class_name , "653624" , $this->Notify_Data['orderNo'] , $this->Notify_Data['payPrice'] , "SUCCESS" , 'FAILED');
    }


    public function YingxuntongNotify(){
        // pay_name 写类名
        if($this->Notify_Data['bank_type'] == 'qq_pay') {
            $Class_name = 'QqPay';
        }elseif($this->Notify_Data['bank_type'] == 'alipay_pay') {
            $Class_name = 'YinxuntongPayAlipay';
        }elseif($this->Notify_Data['bank_type'] == 'WeixinScancode') {
            $Class_name = 'YinxuntongSMPay';
        }elseif($this->Notify_Data['bank_type'] == 'bank_pay'){
            $Class_name = 'YinxuntongPayBank';
        }
        $this->KeyValname($Class_name , $this->Notify_Data['mch_id'] , $this->Notify_Data['order_number'] , $this->Notify_Data['money'] , "SUCCESS" , 'FAILED');
    }

    // 威富通的回调地址不允许带参数
    public function WeifutongpayNotify(){
        if($this->Notify_Data == 'pay.weixin.native') {
            $Class_name = 'WeiFuTongSMPay';
        }else{
            $Class_name = 'WeiFuTongPay';
        }
        $this->KeyValname($Class_name , $this->Notify_Data['mch_id'] , $this->Notify_Data['out_trade_no'] , $this->Notify_Data['total_fee'] / 100 , "success" , 'FAILED');
    }

    public function WeifuPayNotify(){
        $Class_name = 'WeifuPay';
        $this->KeyValname($Class_name , $this->Notify_Data['merchant_code'] , $this->Notify_Data['order_no'] , $this->Notify_Data['order_amount'], "success" , 'FAILED');
    }

    public function WeifuPayH5Notify(){
        $Class_name = 'WeifuPayH5';
         $this->KeyValname($Class_name , $this->Notify_Data['merchant_code'] , $this->Notify_Data['order_no'] , $this->Notify_Data['order_amount'], "success" , 'FAILED');
    }

    public function QuxunPayNotify(){
//        file_put_contents('./quxun.txt' , var_export($this->Notify_Data , true));
        // remark是通道方的自定义扩展字段
        $Class_name = 'QuxunPay';
        $this->KeyValname($Class_name , $this->Notify_Data['remark'] , $this->Notify_Data['buss_order_num'] , $this->Notify_Data['pay_discount_money'], "SUCCESS" , 'FAILED');
    }


    public function TonglianNotifyGzh(){
        $Class_name = 'TonglianPay';
        $this->KeyValname($Class_name , $this->Notify_Data['cusid'] , $this->Notify_Data['cusorderid'] , $this->Notify_Data['trxamt'] / 100 , "success" , 'FAILED');
    }

    public function MeilianPayNoyify(){
        $Class_name = 'MeilianPay';
        // extrdata 这个参数是我自己传的
        $this->KeyValname($Class_name , $this->Notify_Data['extrdata'] , $this->Notify_Data['orderid'] , $this->Notify_Data['amount'] , "success" , 'FAILED');
    }

    public function YuetengPayNoyify(){
        $Class_name = 'YueTengPay';
//        file_put_contents('./n.txt' , var_export($this->Notify_Data , true));
        $this->KeyValname($Class_name , $this->Notify_Data['mch_id'] , $this->Notify_Data['out_trade_no'] , $this->Notify_Data['amount_fee'] / 100 , "success" , 'FAILED');
    }


    public function XGzhNotifyGzh(){
        $Class_name = 'XGzhPay';
        $this->KeyValname($Class_name , $this->Notify_Data['merNo'] , $this->Notify_Data['orderNo'] , $this->Notify_Data['amount'] / 100 , "success" , 'FAILED');
    }

    public function OuchuangAlipaySMPay(){
        echo 'hello word';
    }

    public function AibeiPayNotify(){
        $Class_name = 'AibeiPay';
        $CallbackData = json_decode($this->Notify_Data['transdata'] , true);
        $this->KeyValname($Class_name , $CallbackData['appid'] , $CallbackData['cporderid'] , $CallbackData['money'] , "success" , 'FAILED');
    }

    public function WanYouFuPayNotify(){
        $Class_name = 'WanYouFuPay';
//        file_put_contents('./wanyoufu.txt' , var_export($this->Notify_Data , true));
        $this->KeyValname($Class_name , $this->Notify_Data['app_id'] , $this->Notify_Data['order_id'] , $this->Notify_Data['pay_amt'], "ok" , 'FAILED');
    }

    public function WeizhifuNotify(){
        $Class_name = 'YueTengPay';
        file_put_contents('./weizhifu.txt' , var_export($this->Notify_Data , true));
        exit("SUCCESS");
        $this->KeyValname($Class_name , $this->Notify_Data['app_id'] , $this->Notify_Data['order_id'] , $this->Notify_Data['pay_amt'], "success" , 'FAILED');
    }

    public function LvyiPayNotify(){
        $Class_name = 'LvyiPay';
        $this->KeyValname($Class_name , $this->Notify_Data['customerNo'] , $this->Notify_Data['externalId'] , $this->Notify_Data['amount'] / 100, "success" , 'FAILED');
    }

    /* 得成回调没有返回支付类型，所以接支付宝需要单开一个方法 */
    public function DechengNotify(){
        $Class_name = 'DechengSMPay';
        $this->KeyValname($Class_name , $this->Notify_Data['userId'] , $this->Notify_Data['requestId'] , $this->Notify_Data['amount'] / 100, "000000" , 'FAILED');
    }

    public function DechengAlipayNotify(){
        $Class_name = 'DechengAlipayPay';
        $this->KeyValname($Class_name , $this->Notify_Data['userId'] , $this->Notify_Data['requestId'] , $this->Notify_Data['amount'] / 100, "000000" , 'FAILED');
    }

    public function zhongyiPayNotify(){
        file_put_contents('./zhongyi.txt' , var_export($this->Notify_Data , true));
        $Class_name = 'zhongyiPay';
        $this->KeyValname($Class_name , $this->Notify_Data['userId'] , $this->Notify_Data['requestId'] , $this->Notify_Data['amount'] / 100, "000000" , 'FAILED');
    }

    public function YimatongNotify(){
        $Class_name = 'YiMatong';
        $datas = json_decode(file_get_contents('php://input') , true);
        $this->KeyValname($Class_name , '35045' , $datas['terminal_trace'] , $this->Notify_Data['total_fee'] / 100, "success" , 'FAILED');
    }

    public function RyfXundaNotify(){
        $Class_name = 'RyfXunda';
        $this->KeyValname($Class_name , $this->Notify_Data['mch_id'] , $this->Notify_Data['orderId'] , $this->Notify_Data['amount'], "success" , 'FAILED');
    }

    public function WeipaiNotify(){
        $Class_name = 'WeiPaiPay';
        $this->KeyValname($Class_name , "58983eec26cb4c51df25b115e27894d7" , $this->Notify_Data['cpparam'] , $this->Notify_Data['price'], "success" , 'FAILED');
    }

    public function HaofuPayNotify(){
        $Class_name = 'HaofuPay';
        $data = json_decode(base64_decode($this->Notify_Data['resp']) , true);
        $this->KeyValname($Class_name , $data['merid'] , $data['orderid'] , $data['txnamt'] / 100, "0000" , 'FAILED');
    }

    public function ChangjieNotify(){
        $Class_name = 'ChangJiePay';
        $this->KeyValname($Class_name , '200001160101' , $this->Notify_Data['outer_trade_no'] , $this->Notify_Data['trade_amount'], "success" , 'FAILED');
    }

//    public function ShandePayNotify(){
//        $Class_name = 'ShandeGzhPay';
//        $this->KeyValname($Class_name , '200001160101' , $this->Notify_Data['outer_trade_no'] , $this->Notify_Data['trade_amount'], "success" , 'FAILED');
//    }

    public function PFPayNotify(){
        $Class_name = 'PFPay';
        $this->KeyValname($Class_name , $this->Notify_Data['subMchId'] , $this->Notify_Data['orderNo'] , $this->Notify_Data['transAmt'] / 100, "SUCCESS" , 'FAILED');
    }

    public function Pay98Notify(){
        $Class_name = 'Pay98';
        $price = (string)$this->Notify_Data['amount'];
//        file_put_contents('./log.txt' , var_export($this->Notify_Data , true));
        $this->KeyValname($Class_name , $this->Notify_Data['mch_no'] , $this->Notify_Data['out_trade_no'] , $this->Notify_Data['amount'] / 100, "success" , 'FAILED');
    }

    public function YipiaolianNotify(){
        $Class_name = 'YipiaolianPay';
        $this->KeyValname($Class_name , $this->Notify_Data['partner'] , $this->Notify_Data['out_trade_no'] , $this->Notify_Data['amount'], "success" , 'FAILED');
    }

    private function KeyValname($Class_name , $mch_id , $order_number  , $pay_money , $success_msg , $fail_msg , $wx_orderId = ''){
        $pay_info = array(
            'mch_id' => $mch_id,
            'order_number' => $order_number,
            'pay_money' => $pay_money,
            'success_msg' => $success_msg,
            'fail_msg' => $fail_msg
        );
        if($pay_info['mch_id'] == '' || $pay_info['order_number'] == '')  exit($pay_info['fail_msg']);
        \Think\Log::write("Callback-" . json_encode($this->Notify_Data,JSON_UNESCAPED_UNICODE), 'INFO', '', LOG_PATH . "Api/CallbackLog/". $Class_name ."/" . date('Y-m-d') . ".log");
        $this->Notify($Class_name,$pay_info , $wx_orderId); // 通用接口回调方法
    }

    // 回调与成功处理方法
    private function PaySuccess($order_number,$notify_noney,$payName , $wx_orderId = ''){
        if(empty($order_number)) return false;
        // select a.*,b.merchant_key,c.notify_url as userNotifyUrl,c.id as userid from zym_transaction as a LEFT JOIN zym_merchant as b on a.merchant = b.merchant_id left join zym_user as c on b.userid = c.id where systrade_no = '20170611491006118051391796';
// select a.*,b.merchant_key,c.notify_url as userNotifyUrl,c.id as userid from zym_transaction as a LEFT JOIN zym_merchant as b on a.merchant = b.merchant_id left join zym_user as c on b.userid = c.id
        $transactionDataModel = M('Transaction');

             $transactionData = $transactionDataModel->alias('a')
            ->field('a.*,b.merchant_key,c.notify_url as userNotifyUrl,c.id as userid')
            ->join('LEFT JOIN zym_merchant as b on a.merchant = b.merchant_id left join zym_user as c on b.userid = c.id')
                 // ->where(array('systrade_no' => $order_number)) // 用商户订单号
            ->where(array('out_trade_no' => $order_number))
            ->find();

      // 允许渠道重复通知

        if($transactionData){  // 存在订单，签名过
            //充值金额
            $pay_money    = $order_money = $transactionData['paymoney'];
            $merchant_id      = $transactionData['merchant'];
            if($notify_noney != $transactionData['paymoney']){
                // 订单金额与通知金额不合法不允许通知
                exit('fail');
            }

            if($transactionData['pay_status'] == 0  && $transactionData['update_begtime'] == 0) {
                // 第一次进行异步通知
                $transactionDataModel->startTrans();   //开启事务
                $time = time();
                $saveData = array(
                    'pay_status' => 1,
                    'update_begtime' => $time,
                ); // 更新充值状态

                // systrade_no  out_trade_no  // 直接用传来的订单号和用充值系统的商户号

                @M('mch_data')->where(array('mch_id' => $transactionData['mch_id']))->setInc('CumulativePrice' , $pay_money);
                @M('mch_data')->where(array('mch_id' => $transactionData['mch_id']))->setInc('penNum' , 1);

                $update_orderstatus = M('Transaction')->where(array('out_trade_no' => $order_number))->save($saveData);
                $update_orderstatus_after = M('Transaction')->where(array('pay_status' => 1, 'out_trade_no' => $order_number))->getField('pay_status');
                @M("User")->where(array('id' => $transactionData['userid']))->setInc('money',$transactionData['paymoney']);
                if ($update_orderstatus && $update_orderstatus_after == 1) {
                    \Think\Log::write("PaySuccess-" . $order_number, 'INFO', '', LOG_PATH . "Api/CallbackLog/". $payName ."/" . date('Y-m-d') . ".log");
                    $transactionDataModel->commit();
                } else {
                    $transactionDataModel->rollback();
                    return false;
                }
            }
            $update_orderstatus_tow = M('Transaction')->where(array('pay_status' => 1 , 'out_trade_no' => $order_number))->find(); // 防止第二次异步通知时查询

            // 异步通知
            if($update_orderstatus_tow['pay_status'] == 1){
                $nonce_str = guid(); // 生成无重复随机字符串
                // 加入签名的参数
                $NotifySignData = array(
                    // 异步通知参与的Sign参数
                    'partner' => $merchant_id ,
                    'ordernumber' => $transactionData['out_trade_no'] , // 用户支付时传入的订单号
                    'orderstatus' => '1' ,
                    'bank_type' => $transactionData['pay_type'] ,
//                    'wx_orderId' => $wx_orderId, // 微信订单号，如果有则返回没有则返回空参数
                    // 新加
                    'passageway_id' => $transactionData['mch_id'], // 渠道商户号
                    'passageway_type' => $transactionData['mch_type'], // 渠道名
                    // 新加 The End
                    'nonce_str' => $nonce_str, // 无重复随机字符串
                    'paymoney' => $pay_money
                );

                $NotifySign = SetMySign($NotifySignData,$transactionData['merchant_key']);

                // 发送异步回调通知的参数
                $Send_NotifyData = array(
                    'partner' => $merchant_id,
                    'ordernumber' => $transactionData['out_trade_no'], // 用户支付时传入的订单号
                    'orderstatus' => '1',
                    'paymoney' => $pay_money,
                    'bank_type' => $transactionData['pay_type'] ,
//                    'wx_orderId' => $wx_orderId,
                    'sysnumber' => $transactionData['systrade_no'], // 系统订单号
                    // 新加
                    'passageway_id' => $transactionData['mch_id'], // 渠道商户号
                    'passageway_type' => $transactionData['mch_type'], // 渠道名
                    // 新加 The End
                    'nonce_str' => $nonce_str,
                    'sign'      => $NotifySign
                );


//                file_put_contents('./notifyConfig.txt',var_export($Send_NotifyData,true));
                $SendNotifyResult = https_request($transactionData['notify_url'],$Send_NotifyData);
//                file_put_contents('./notifyConfig_after.txt',$SendNotifyResult);

                // 只有使用接口方 输出SUCCESS，我才给渠道方返回成功的标识
//                if(NotifyechoMessage($successmsg , $SendNotifyResult) != 'SUCCESS') {
//                    Putdd('towNotify.txt' ,  'tow-' . date('Y:m:d H:i:s' , time()));
//                    echo $successmsg;
//                }else{
//                    echo 'fail';
//                }

                $file_name = './PayStatusLog/' . $Send_NotifyData['ordernumber'] . '.txt';
                if(!file_exists($file_name)){
                    file_put_contents($file_name , $SendNotifyResult);
                }

                if($SendNotifyResult != "SUCCESS") {
                    return false;
                }else{
                    return true;
                }
            }

        }
    }

}